package se.lnu.axez.textures;

import se.lnu.axez.shaders.ShaderProgram;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLUtils;

public abstract class BitmapTexture2D implements ITexture {
	private int textureID;
	
	protected BitmapTexture2D() {
	}

	@Override
	public final void load() {
		final int[] idReceiver = new int[1];
		GLES20.glGenTextures(idReceiver.length, idReceiver, 0);
		this.textureID = idReceiver[0];

		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.textureID);
		
		final Bitmap bmp = this.getBitmap();
		try {
			GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
		} finally {
			bmp.recycle();
		}
		
		GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
		GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
	}

	@Override
	public final void use(ShaderProgram shaderProgram) {
		int uniID = shaderProgram.getUniformID(this.getUniformName());
		if (uniID != ShaderProgram.INVALID_ID) {
			// TODO: reconsider
			GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
			GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.textureID);
			GLES20.glUniform1i(uniID, 0);
		}
	}
	
	public final void release() {
		final int[] idReceiver = new int[1];
		idReceiver[0] = this.textureID;
		GLES20.glDeleteTextures(idReceiver.length, idReceiver, 0);
	}
	
	protected abstract Bitmap getBitmap();
	protected abstract String getUniformName();
	
	protected static boolean isPowerOf2(int val) {
		return (val > 0 && ((val & (val - 1)) == 0));
	}
}
